#ifndef _MESSAGE_
#define _MESSAGE_

#include<string>
#include<unordered_map>
#include<cmath>
#include<iostream>
#include"threadPool.hpp"
#include"room.hpp"

using namespace std;

extern rooms room;

class message;
class notification;
class rawMessage;

class message
{
protected:
    int type;
    string roomNo;
    int fd;
public:
    message(int _type,const string& _roomNo,int _fd):type(_type),roomNo(_roomNo),fd(_fd) {}
    virtual bool process()=0;
};

class request:public message
{
private:
    bool isOpen;
    double temperature;
    int wind;
public:
    request(const string &_roomNo,int _fd,bool _isOpen,double _temperature,int _wind):
        message(0,_roomNo,_fd),isOpen(_isOpen),temperature(_temperature),wind(_wind) {}
    bool process()
    {
        if(room.isExist(this->roomNo)){
            room.modify(this->roomNo,this->temperature,this->wind,this->isOpen);
        }
        else{
            room.insert(this->roomNo,roomInfo(this->roomNo,this->isOpen,this->wind,this->temperature,25));
        }
        return true;
    }
};

class notification:public message
{
private:
    double temperature;
public:
    notification(const string& _roomNo,int _fd,double _temperature):
        message(1,_roomNo,_fd),temperature(_temperature) {}
    bool process()
    {
        if(room.isExist(this->roomNo)){
            room.charge(this->roomNo,this->temperature);
        }
        else
        {
            room.insert(this->roomNo,roomInfo(this->roomNo,false,0,25,temperature));
        }
        room.feedBack(this->roomNo,this->fd);
        return true;
    }
};

class rawMessage
{
private:
    string jsonText;
    int fd;
public:
    rawMessage(const string& _jsonText,int _fd):jsonText(_jsonText),fd(_fd) {}
    bool process()
    {
        cout<<"tid:"<<pthread_self()<<endl;
        Json::Reader reader;
        Json::Value value;
        reader.parse(jsonText,value);
        if(value["type"].asInt()==0)
        {
            string roomNo=value["room"].asString();
            bool isOpen=value["switch"].asBool();
            double temperature=value["temperature"].asDouble();
            int wind=value["wind"].asInt();
            request tmp(roomNo,fd,isOpen,temperature,wind);
            tmp.process();
        }
        else if(value["type"].asInt()==1)
        {
            string roomNo=value["room"].asString();
            double temperature=value["temperature"].asDouble();
            notification tmp(roomNo,fd,temperature);
            tmp.process();
        }
        return true;
    }
};

#endif
